package online.longzipeng.mywebdemo;

import cn.hutool.core.lang.generator.SnowflakeGenerator;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.SetOperations;

import java.time.LocalDate;
import java.util.UUID;

/**
 * @Author: lzp
 * @description:
 * @Date: 2022/8/20
 */
@Slf4j
@SpringBootTest(classes = MyWebDemoApplication.class,
        // 配置端口启动，否则获取失败
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ShortIdDemo {

    @Autowired
    private SnowflakeGenerator snowflakeGenerator;
    @Autowired
    private SetOperations<String, Object> setOperations;

    private static String SHORT_ID_SET_KEY = "short_id_set";
    private static int max_retry_count = 10;
    private static int record_max_retry_count = 0;

    @Test
    public void testShortId() {
        for (int i = 0; i < 5000; i++) {
            System.out.println(generate());
        }
        System.out.println("最大重试次数为：" + record_max_retry_count);
    }

    public Long generate() {
        Long shortId = null;
        boolean exists = true;
        int count = 0;
        while (exists) {
            if (count > record_max_retry_count) {
                record_max_retry_count = count;
            }
            if (count > max_retry_count) {
                log.error("超过最大重试次数，请维护人员检查一下");
                return null;
            }
            shortId = generateShortId();
            exists = setOperations.add(SHORT_ID_SET_KEY, shortId.toString()) == 0;
            count++;
        }
        return shortId;
    }

    private static Long generateShortId() {
        // 2 位 年份的后两位 22001 后五位走随机  每天清一次缓存 99999 10
        StringBuilder idSb = new StringBuilder();
        /// 年份后两位  和  一年中的第几天
        LocalDate now = LocalDate.now();
        String year = now.getYear() + "";
        year = year.substring(2);
        String day = now.getDayOfYear() + "";
        /// 补0
        if (day.length() < 3) {
            StringBuilder sb = new StringBuilder();
            for (int i = day.length(); i < 3; i++) {
                sb.append("0");
            }
            day = sb.append(day).toString();
        }
        idSb.append(year).append(day);
        /// 后五位补随机数
        for (int i = idSb.length(); i < 10; i++) {
            idSb.append((int) (Math.random() * 10));
        }
        return Long.parseLong(idSb.toString());
    }

    /**
     * 设计实现 生成不重复10位纯数字短ID工具类
     * 9999999999    10 亿 不重复的短id ，  redis set集合，  不重复=>插入 重复 =>重试
     * 1000万 =》 撑 redis
     * 固定n位 按一定的规律进行变化， 后面的m位 就完全走随机数
     * 2 位 年份的后两位 22001 后五位走随机  每天清一次缓存 99999 10
     */
    @Test
    public void test1() {
        Long snowflakeId = snowflakeGenerator.next();
        String uuid = UUID.randomUUID().toString();
        String uid = uuid.replace("-", "");
        log.info("uuid=>{} 长度为=>{}", uuid, uuid.length());
        log.info("uid=>{} 长度为=>{}", uid, uid.length());
        log.info("snowflakeId=>{} 长度为=>{}", snowflakeId, snowflakeId.toString().length());
    }

}
